/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package tpgen;

import java.util.Collection;
import java.util.Date;
import java.util.Random;
import tpgen.grammar.Grammar;
import tpgen.grammar.Variable;
import tpgen.grammar.Variables;
import tpgen.manchester.ManchesterFactory;
import tpgen.manchester.w3org.Construct;
import tpgen.patterns.Axiom;
import tpgen.patterns.Axioms;
import tpgen.patterns.Eq;
import tpgen.patterns.EqHet;
import tpgen.patterns.OntologyPattern;
import tpgen.patterns.PatternTransformation;
import tpgen.patterns.TransformationPattern;

/**
 *
 * @author shanki
 */
public class GenericGenerator {

    Axioms generate(Grammar grammar, Variables vars, int count) {
        Axioms axioms   = new Axioms();
        
        for (int i = 0; i < count; ++i) {
            axioms.add(new Axiom(grammar.generateExpression(vars)));
        }

        return axioms;
    }

    public TransformationPattern generate(int maxVarsPerType, int maxAxioms, int maxTransformations, Collection<Construct> inputForbiddenConstructs, Collection<Construct> outputForbiddenConstructs) {
        ManchesterFactory factory       = new ManchesterFactory();
        
        Grammar inputGrammar    = factory.createGrammar(inputForbiddenConstructs);
        Grammar outputGrammar   = factory.createGrammar(outputForbiddenConstructs);
        
        Random rg       = new Random(new Date().getTime());
                       
        Variables varsA  = inputGrammar.generateVars("var_a_", maxVarsPerType);
        
        Axioms ax1   = generate(inputGrammar, varsA, rg.nextInt(maxAxioms)+1);    
        OntologyPattern op1 = new OntologyPattern(ax1);
        
        Variables varsB = outputGrammar.generateVars("var_b_", maxVarsPerType);
        
        Axioms ax2   = generate(outputGrammar, varsB, rg.nextInt(maxAxioms)+1);
        OntologyPattern op2 = new OntologyPattern(ax2);
        
        Variables varsAused = new Variables(op1.getVars());
        Variables varsBused = new Variables(op2.getVars());
        int transformations = rg.nextInt(maxTransformations)+1;

        PatternTransformation pt = generate(rg, varsAused, varsBused, transformations);
        
        return new TransformationPattern(op1,op2,pt);
    }
    
    private PatternTransformation generate(Random rg, Variables varsA, Variables varsB, int transformations) {
        PatternTransformation pt = new PatternTransformation();
        
        for (int i = 0; i < transformations; ++i) {
            if (varsA.isEmpty() == false && varsB.isEmpty() == false) {
                
                Variable a = varsA.random(rg);
                Variable b = varsB.random(rg);

                if (a.sameType(b)) {
                    pt.add(new Eq(a,b));
                } else {
                    pt.add(new EqHet(a,b));
                }
                
                varsA = varsA.remove(a);
                varsB = varsB.remove(b);
            }
        }
        
        return pt;
    }

}
